/*
 * ConexionPeerCliente.cpp
 *
 *  Created on: Jun 15, 2009
 *      Author: joephantom
 */

#include "ConexionPeerCliente.h"

ConexionPeerCliente::ConexionPeerCliente(const string &infoHash, const string &peerId):
	ConexionPeer(infoHash, peerId)
	{
	}

ConexionPeerCliente::~ConexionPeerCliente()
{
}

bool ConexionPeerCliente::bidireccionalHandshake(string &peerId) const
{
	string peerIdRecibido;

	if(this->handshake()){
		if(this->recibirHandshake(peerIdRecibido)){
			peerId = peerIdRecibido;
			return true;
		}
	}

	return false;
}

bool ConexionPeerCliente::handshake() const{
	unsigned char c= 19;
	string aux;

	aux.append(1,c);
	aux.append("BitTorrent protocol");
	aux.append("        ");
	aux.append(this->infoHash);
	aux.append(this->peerId);

	cout << "handshake " << aux << endl; //TODO BORRAR

	return this->socket.send(aux.c_str(), aux.size());
}

bool ConexionPeerCliente::recibirHandshake(string &peerId) const
{
	char aux[68];
	bool flag = this->socket.recv(aux, 68); //TODO VERIFICAR que el chabon mande 68 bytes. En caso contrario devolver false

	if(flag){
		char pstrlen = 0;
		string pstr;
		string hashPeer;
		string auxPeerId;

		pstrlen = aux[0];
		pstr.append(aux+1);
		hashPeer.append(aux+28, 20);
		auxPeerId.append(aux+48, 20);

		if((pstrlen == 19) &&
				(pstr == "BitTorrent protocol") &&
				(hashPeer == this->infoHash)){ //TODO guardar constantes 19 y bittorrent protocol
			peerId = auxPeerId;
			return true;
		} else {
			return false;
		}
	}

	return false;
}

bool ConexionPeerCliente::enviar(const string &s) const
{
	unsigned long int tamano = htonl(s.size());
	char aux[4];
	string copiaS = "";

	memcpy(aux, &tamano, 4);

	copiaS.append(aux, 4);
	copiaS.append(s);

	return this->socket.send(copiaS.c_str(), copiaS.size());
}

bool ConexionPeerCliente::recibir(string &s) const
{
	bool flag1, flag2;
	unsigned long int tamano = 0;
	char aux[4];
	flag1 = this->socket.recv(aux ,4);

	if(flag1){
		memcpy(&tamano, aux, 4);

		tamano = ntohl(tamano);

		if (tamano == 0){ //mensaje de tipo keep alive
			s = "";
			return true;
		}

		char *message = new char[tamano];

		flag2 = this->socket.recv(message,tamano);
		if(flag2){
			s.append(message, tamano);
		}
		delete message;
	}

	return (flag1 && flag2);
}
